package cas;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicMarkableReference;
import java.util.concurrent.atomic.AtomicStampedReference;

//CAS compareAndSwap全称  比较并交换 期望值2020 希望修改为2021，通过比较如果2020变了则不会进行修改，反之修改为2021
//最常见的问题是ABA问题，2020-2021过程中有人把2020修改为了2021，之后又把2021修改为了2020，看似2020本身没变，但是已经有人修改过了
//解决办法类似乐观锁。加一个版本号，每次修改都比较版本号
public class CASDemo {

    public static void main(String[] args) {

        AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<Integer>(110, 1);

        //中途修改
        new Thread(()->{
            //修改一次115
           int stamp =  atomicStampedReference.getStamp();
            System.out.println("a1-> "+ stamp);

            try {
                TimeUnit.SECONDS.sleep(1);
                 } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("A第一次修改"+atomicStampedReference.compareAndSet(110, 115, stamp, stamp + 1));
            //在修改回去110
            System.out.println("a2->"+atomicStampedReference.getStamp());

            System.out.println("A改回去"+atomicStampedReference.compareAndSet(115, 110, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1));
            System.out.println("a3-> " + atomicStampedReference.getStamp());
        },"a").start();
        //正常读取
        new Thread(() -> {
           int stamp =  atomicStampedReference.getStamp();
            System.out.println("b1->"+stamp);
            try {
                TimeUnit.SECONDS.sleep(2);
            }catch (Exception e){
                e.printStackTrace();
            }
            System.out.println("B修改"+atomicStampedReference.compareAndSet(110, 55, stamp, stamp + 1));
            System.out.println("b2-> "+atomicStampedReference.getStamp());
            System.out.println("return=="+atomicStampedReference.getReference());
        },"b").start();
    }
}
